home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / bltq13a.zip / BORLAND.ZIP / MEMCXB.ASM < prev    next >
Assembly Source File  |  1993-07-22  |  12KB  |  233 lines

  1. TITLE MEMCXB      ;C version
  2. PAGE 55,132
  3. ;multiple routines
  4. ;xb$malloc
  5. ;xb$free
  6. ;xb$SetHandleCount  (no longer available with this replacement module)
  7. ;-----------------------------------------------------------------------|
  8. ;    ScanSoft          (C)1992 Cornel H Huth     ALL RIGHTS RESERVED    |
  9. ;-----------------------------------------------------------------------|
  10. ;     date:      30-Sep-92                                              |
  11. ; function:      Memory routines for C compilers                        |
  12. ;                that do not allow DOS allocations to be mixed with     |
  13. ;                _malloc allocations (including _calloc, etc.)          |
  14. ;    notes:      This malady afflicts Borland C compilers               |
  15. ;                All registers saved since there's no telling what      |
  16. ;                registers the runtime code uses (ax,bp not saved)      |
  17. ;                                                                       |
  18. ;                                                                       |
  19. ;The code below will work in either LARGE or HUGE memory modules.       |
  20. ;It will not, as written, work in the medium model. With minor changes, |
  21. ;the medium model could be supported.                                   |
  22. ;                                                                       |
  23. ;This code was written with MASM 5.10A in mind though TASM should       |
  24. ;handle it, too.                                                        |
  25. ;                                                                       |
  26. ;To assemble:                                                           |
  27. ;                                                                       |
  28. ;       C>masm memcxb /mx;   (/mx=preserve case on globals)             |
  29. ;                                                                       |
  30. ;You can then use either of the following methods:                      |
  31. ;                                                                       |
  32. ; Replace MEMXB.OBJ in BULLET.LIB:                                      |
  33. ;                                                                       |
  34. ;        C>lib BULLET -memxb +memcxb;                                   |
  35. ;                                                                       |
  36. ; Or, leave BULLET.LIB as is but place MEMCXB.OBJ on the link line with |
  37. ; the other object modules. This will, however, cause the linker to     |
  38. ; issue the warning "DUPLICATE SYMBOL DEFINITION". This is expected.    |
  39. ; The linker will use the code in MEMCXB.OBJ and ignore the memxb module|
  40. ; in BULLET.LIB.                                                        |
  41. ;                                                                       |
  42. ;-----------------------------------------------------------------------|
  43. WPTR EQU <WORD PTR>
  44.  
  45.                 .MODEL LARGE,PASCAL
  46.  
  47.                 .CODE
  48.  
  49. EXTRN _malloc:FAR
  50. EXTRN _free:FAR
  51.  
  52.                 ;The Tracker lists are allocated in code segment to minimize
  53.                 ;impact on DGROUP
  54.  
  55.                 ;MAXTRACKER is the number of allocations that can be open at
  56.                 ;any one time. Consider each open file to require one Track.
  57.                 ;A good MAXTRACKER value would be the total number of files you
  58.                 ;require to be open at one time plus 5. Each MAXTRACKER
  59.                 ;requires 6 bytes of code space. Unless you're starving for
  60.                 ;RAM, MAXTRACKER is fine at 254 (uses about 1.5K of code space.)
  61.  
  62. MAXTRACKER EQU 254
  63.  
  64.                 ;TrackerFP stores far pointers as returned by _malloc
  65.                 ;so that _free can be used (_free requires exact FP match)
  66. EVEN
  67. TrackerFP       dd MAXTRACKER DUP (0)   ;32-bit pointer as returned by _malloc
  68.                 dd 0                    ;and required by _free
  69.  
  70.                 ;TrackerSeg stores the 16-bit segment pointer converted from
  71.                 ;the far pointer returned by _malloc. See xb$malloc for how
  72.                 ;this is done. This is used as a lookup value in xb$free.
  73.  
  74. TrackerSeg      dw MAXTRACKER DUP (0)   ;thunk it to a 16-bit segment pointer
  75.                 dw -1
  76.  
  77. ;-----------------------------------------------------------------------|
  78. ;     date:      30-Sep-92                                              |
  79. ; function:      allocate memory                                        |
  80. ;   caller:      FAR, ASSEMBLY                                          |
  81. ;    stack:      n/a                                                    |
  82. ;       in:      bx=paragraphs to allocate                              |
  83. ;      out:      NC=ax=seg                                              |
  84. ;                CY=ax=8=not enough memory                              |
  85. ;     uses:      ax (return),bx                                         |
  86. ;    notes:      call with bx=FFFF and bx returns w/ largest block free |
  87. ;                (according to DOS)                                     |
  88. ;chh: removed bx save on xb$malloc                                      |
  89. ;-----------------------------------------------------------------------|
  90.  
  91. XB$MALLOC       PROC USES cx dx si di es ds
  92.  
  93.                 cmp     bx,-1           ;just asking for available memory?
  94.                 jne     xb$malloc01     ;no
  95.                 mov ah,48h              ;yes
  96.                 int 21h
  97.                 jmp     SHORT xb$mallocXit
  98.  
  99. xb$malloc01:    mov     cx,MAXTRACKER   ;scan for next free descriptor
  100.                 sub     ax,ax           ;0 indicates available
  101.                 push    cs
  102.                 mov     di,OFFSET TrackerSeg
  103.                 pop     es              ;es:di->TrackSeg start
  104.                 repne scasw
  105.                 jne     xb$mallocEx     ;none available
  106.                 mov     ax,di
  107.                 sub     ax,OFFSET TrackerSeg+2 ;ax=available slot (word)
  108.  
  109.                 push    ax              ;save slot
  110.  
  111.                 sub     ax,ax
  112.                 push    ax              ;high-word of request
  113.                 mov     ax,bx           ;paras requested
  114.                 inc     ax              ;bump para request so we can norm it
  115.                 shl     ax,1            ;(thunk it would be more like it)
  116.                 shl     ax,1
  117.                 shl     ax,1
  118.                 shl     ax,1            ;paras to bytes
  119.                 push    ax              ;low-word of request
  120.                 call    _malloc         ;appease the Borland Gods
  121.                 add     sp,4            ;here dx:ax is far pointer to block
  122.  
  123.                 pop     di              ;get back slot
  124.  
  125.                 mov     bx,dx           ;check for null pointer return
  126.                 or      bx,ax           ;allocation okay?
  127.                 jz      xb$mallocEx     ;no
  128.  
  129.                 mov     si,di           ;word slot index for TrackerSeg
  130.                 shl     di,1            ;dword slot index for TrackerFP
  131.                 mov     WPTR cs:[TrackerFP+di],ax
  132.                 mov     WPTR cs:[TrackerFP+di+2],dx
  133.  
  134.                 ;normalize the 32-bit pointer to a 16-bit segment pointer
  135.                 ;we can do this because we requested 1 additional paragraph
  136.                 ;so that we can just drop the normalized offset and start
  137.                 ;using the allocated memory block at the next paragraph
  138.  
  139.                 ;;since we won't be using the fractional-para offset of the
  140.                 ;;norm'ed far pointer we can skip the overhead
  141.  
  142.                 ;;mov     bx,ax           ;save full offset
  143.                 ;;and     ax,000Fh        ;non-paragraph portion
  144.                 ;;mov     cx,ax           ;ax is normalized offset
  145.                 ;;mov     ax,bx           ;get full offset back
  146.  
  147.                 shr     ax,1            ;convert offset to full paras
  148.                 shr     ax,1
  149.                 shr     ax,1
  150.                 shr     ax,1
  151.                 add     ax,dx           ;add segment in
  152.                 inc     ax              ;bump to next paragraph
  153.                 mov     cs:[TrackerSeg+si],ax
  154.                 clc                     ;return 16-bit segment pointer in ax
  155. xb$mallocXit:   ret                     ;that BULLET will use
  156.  
  157. xb$mallocEx:    mov     ax,8
  158.                 stc
  159.                 jmp     SHORT xb$mallocXit
  160.  
  161. XB$MALLOC       ENDP
  162.  
  163. ;-----------------------------------------------------------------------|
  164. ;     date:      30-Sep-92                                              |
  165. ; function:      free allocated memory                                  |
  166. ;   caller:      FAR, ASSEMBLY                                          |
  167. ;    stack:      n/a                                                    |
  168. ;       in:      es=segment pointer of block to free                    |
  169. ;      out:      NC=okay (at least this code, _free has not return code)|
  170. ;                CY=ax=9 invalid block (segment not in descriptor list  |
  171. ;     uses:      ax (return)                                            |
  172. ;    notes:      see xb$malloc above for more info                      |
  173. ;-----------------------------------------------------------------------|
  174.  
  175. XB$FREE         PROC USES bx cx dx si di ds es
  176.  
  177.                 mov     cx,MAXTRACKER   ;scan for matching descriptor
  178.                 mov     ax,es           ;search for this segment pointer
  179.                 push    cs
  180.                 mov     di,OFFSET TrackerSeg
  181.                 pop     es              ;es:di->TrackerSeg start
  182.                 repne scasw
  183.                 jne     xb$freeEx       ;not found, must be invalid block
  184.  
  185.                 sub     ax,ax
  186.                 sub     di,OFFSET TrackerSeg+2  ;di=matched slot (word)
  187.  
  188.                 push    di                      ;save slot
  189.  
  190.                 shl     di,1                    ;dword slot index
  191.                 push    WPTR cs:[TrackerFP+di+2];segment to block to release
  192.                 push    WPTR cs:[TrackerFP+di]  ;offset
  193.                 call    _free                   ;appease them some more
  194.                 add     sp,4
  195.                 sub     ax,ax
  196.                 mov     WPTR cs:[TrackerFP+di+2],ax     ;clear descriptor info
  197.                 mov     WPTR cs:[TrackerFP+di],ax
  198.  
  199.                 pop     di                              ;get word slot index
  200.  
  201.                 mov     cs:[TrackerSeg+di],ax           ;make slot available
  202. xb$freeXit:     ret
  203.  
  204. xb$freeEx:      mov     ax,9
  205.                 stc
  206.                 jmp     xb$freeXit
  207. XB$FREE         ENDP
  208.  
  209. ;-----------------------------------------------------------------------|
  210. ;     date:      30-Sep-92                                              |
  211. ; function:      set maximum handle count                               |
  212. ;   caller:      FAR, ASSEMBLY                                          |
  213. ;    stack:      n/a                                                    |
  214. ;       in:      bx=handle count                                        |
  215. ;      out:      NC=okay                                                |
  216. ;                CY=ax=error number                                     |
  217. ;     uses:      ax (return)                                            |
  218. ;    notes:      Cannot use DOS INT21/67 since it makes a DOS memory    |
  219. ;                allocation call which, as you know, cannot be          |
  220. ;                issued when using Borland's _malloc functions.         |
  221. ;-----------------------------------------------------------------------|
  222.  
  223. XB$SETHANDLECOUNT PROC
  224.  
  225.                 mov     ax,1            ;function not available for Borland C
  226.                 stc                     ;via this route
  227.                 ret
  228.  
  229. XB$SETHANDLECOUNT ENDP
  230.  
  231.                 END
  232.  
  233.